﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Chefbook.UserActions
{
    public class UserActionManager
    {
        private Stack<IUserAction> undoStack;
        private Stack<IUserAction> redoStack;

        public UserActionManager()
        {
            undoStack = new Stack<IUserAction>();
            redoStack = new Stack<IUserAction>();
        }
        /// <summary>
        /// Performs a user action an adds it to the undo stack
        /// </summary>
        /// <param name="action"></param>
        public void PerformAction(IUserAction action)
        {
            action.DoAction();
            undoStack.Push(action);
            redoStack.Clear();
        }

        /// <summary>
        /// Undo's the previous action if there is one on the stack
        /// </summary>
        /// <returns>True if an action was undone, else false</returns>
        public bool UndoAction()
        {
            if(undoStack.Count >0)
            {
                IUserAction act = undoStack.Pop();
                act.UndoAction();
                redoStack.Push(act);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Redo's an action that was undone if it's still on the stack.
        /// Redo stack is cleared when a new action is performed.
        /// </summary>
        /// <returns>True if an action was redone, else fals</returns>
        public bool RedoAction()
        {
            if (redoStack.Count > 0)
            {
                IUserAction act = redoStack.Pop();
                act.DoAction();
                undoStack.Push(act);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Number of undoable actions recorded
        /// </summary>
        public int UndoableActionsCount
        {
            get { return undoStack.Count; }
        }

        /// <summary>
        /// Number of redoable actions recorded
        /// </summary>
        public int RedoableActionsCount
        {
            get { return redoStack.Count; }
        }

        /// <summary>
        /// Gets the next action to be undone without actually undoing
        /// </summary>
        /// <returns>The next action to be undone</returns>
        public IUserAction PreviewNextUndoAction()
        {
            if (undoStack.Count > 0)
            {
                return undoStack.Peek();
            }
            return null;
        }

        /// <summary>
        /// Gets the next action to be redone without actually redoing
        /// </summary>
        /// <returns>The next action to be redone</returns>
        public IUserAction PreviewNextRedoAction()
        {
            if (redoStack.Count > 0)
            {
                return redoStack.Peek();
            }
            return null;
        }
    }
}
